import {
  initState
} from "./observe";
import Watcher from "./observe/watcher";
import {
  compile
} from './utils';

function Vue(options) {
  this._init(options);
}

Vue.prototype._init = function (options) {
  let vm = this;
  vm.$options = options;

  //mvvm
  //对数据进行初始化
  //对数据进行响应式处理
  initState(vm);

  //页面渲染
  if (vm.$options.el) {
    //挂载
    vm.$mount();
  }

}

//挂载函数
Vue.prototype.$mount = function () {
  let vm = this;
  let el = vm.$options.el;

  //挂载el到vue实例
  el = vm.$el = query(el);

  //更新组件函数
  //该方法在watcher实例化是会执行
  let updataComponent = () => {
    // console.log('updatecomponent');

    //节点获取编译再渲染更新
    vm._update();

  };

  //实例化watcher(渲染watcher)
  //传入实例和函数
  let watcher = new Watcher(vm, updataComponent);

  /**
   * console.log(watcher);
   * Watcher {
   *   vm: Vue {$options: {…}, _data: {…}, $el: div#app, …},
   *   expOrFn: () => { console.log('updatecomponent'); },
   *   cb: () => {},
   *   opts: {},
   *   id: 0
   * }
   */

}


Vue.prototype.$watch = function (expr, handler) {
  let vm = this;

  // console.log(expr);
  //message / number

  // console.log(handler); f(){} / f(){}

  //实例化watcher(渲染watcher)
  new Watcher(vm, expr, handler, {
    user: true
  });
}

//更新函数: 根据数据渲染组件
Vue.prototype._update = function () {
  //拿到用户定义的数据
  let vm = this;
  let el = vm.$el;

  //创建文档碎片
  let node = document.createDocumentFragment();

  //把#app标签底下的所有节点都插入到文档碎片里
  let firstChild;

  while (firstChild = el.firstChild) {
    /**
     * console.log(el.firstChild);
     * 第一次：文本节点
     * 第二次：<input type="text" v-model="message">
     * 第三次：{{message}}
     * 第四次：<div>名字：{{person.name}}年龄：{{person.age}}</div>
     * 第五次：文本节点
     * 第六次：<div>{{nums}}</div>
     * 第七次：文本节点
     */
    node.appendChild(firstChild);
  }

  //编译文本
  compile(node, vm);


  //将文档碎片插入到el 渲染显示页面
  el.appendChild(node);



}

//获取el节点
function query(el) {
  //el有可能是 '#app' 也有可能是querySelector拿到的节点
  if (typeof el === 'string') {
    return document.querySelector(el);
  }
  return el;
}





export default Vue;